<?php

namespace App\Console\Commands;

use App\Models\OldSystem\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redis;

class MigrateOldSystemAgentTeamPerformance extends Command
{
    /**
     * 命令名称及签名
     *
     * @var string
     */
    protected $signature = 'migrate:agent_team_performance';

    /**
     * 命令描述
     *
     * @var string
     */
    protected $description = '迁移老系统的代理商团队业绩';

    /**
     * 代理商总数
     * @var int
     */
    protected $agentCount = 0;

    public function handle()
    {
        /**
         * 整体迁移脚本分三部分,按照顺序执行
         * 一. 代理基本信息 MigrateOldSystemAgentBasicData
         * 二. 代理个人业绩 (优化为 可以分多个进程执行) MigrateOldSystemAgentPerformance
         * 三. 团队业绩 (当前) (优化为 可以分多个进程执行)
         */
        $this->agentCount = User::query()->count();
        $bar = $this->output->createProgressBar($this->agentCount);
        $bar->start();
        User::query()
            ->select(['user_id'])
            ->each(function (User $agent) use (&$bar) {
                try {
                    $userId = $agent['user_id'];
                    // 是否已经完成过了
                    if (0 !== Redis::hexists('migrate:agent_team_performance', $userId)) {
                        return true;
                    }

                    // 获取单个用户操作锁
                    // 一小时的锁 ... 太长就有问题了, 这用户也太厉害了
                    Cache::lock('migrate:agent_' . $userId . '_team_performance_lock', 1 * 60 * 60)
                        ->get(function () use ($userId) {
                            $teamPerformance = $this->teamPerformance($userId); // 团队业绩

                            \DB::table('agents')->where('id', $userId)->update([
                                'team_performance' => $teamPerformance,
                                // 2020-10-23 15:16:55 这里老数据迁移的时候 用错了,应该是减号 - 相隔, 会用脚本修复数据 2020-10-23 16:03:21 已修复
                                'parent_path_id' => implode(',', $this->getAgentSuperiorsList($userId)) // 上级路径
                            ]);

                            // 记录用户团队业绩 (也作为完成操作标识)
                            Redis::hset('migrate:agent_team_performance', $userId, $teamPerformance);
                        });

                    $bar->advance(1);
                } catch (\Exception $e) {
                    $this->output->error($e->getMessage());
                }

                return true;
            }, 2000);
        $bar->finish();
    }

    /**
     * 获取代理商上级路径
     * @param $agentId
     * @return array
     */
    public function getAgentSuperiorsList($agentId)
    {
        $superiorList = [];
        $findDirectInviter = function ($id) use (&$findDirectInviter, &$superiorList) {
            if ($directInvitor = Redis::hget('migrate:agent_direct_invitor', $id)) {
                array_unshift($superiorList, $directInvitor); // 推入上级数组, 上级到下级 从左到右
                $findDirectInviter($directInvitor);
            }
        };
        $findDirectInviter($agentId);

        return $superiorList;
    }

    /**
     * 团队业绩 下(和下下)级 的业绩汇总,数据来源依托于 迁移步骤2 MigrateOldSystemAgentPerformance
     * @param $agentId
     * @return int
     */
    public function teamPerformance($agentId)
    {
        $subordinate = json_decode(Redis::hget('migrate:agent_subordinate', $agentId));
        $teamPerformance = 0;

        foreach ($subordinate as $_agentId) {
            $teamPerformance += Redis::hget('migrate:agent_performance', $_agentId);
        }

        return $teamPerformance;
    }
}
